home *** CD-ROM | disk | FTP | other *** search
/ Amiga Game-Power / Amiga Game-Power.iso / pd mix ii / rot / snake / snake.c < prev    next >
C/C++ Source or Header  |  1994-05-20  |  9KB  |  331 lines

  1. /*****************************************************************
  2. ** Snake.c - KABjorke 30 March 87                **
  3. ** © 1987, National Pixel Products                **
  4. ** Released to the Public Domain for Non-Commercial Purposes.    **
  5. **    A variant on the old "bouncing lines" program.        **
  6. **    This version uses multiple vertices and Bezier splines.    **
  7. *****************************************************************/
  8.  
  9. #include <exec/types.h>
  10. #include <exec/nodes.h>
  11. #include <exec/lists.h>
  12. #include <intuition/intuition.h>
  13. #include <graphics/gfx.h>
  14. #include <graphics/text.h>
  15.  
  16. #define MAXVERT 15
  17.  
  18. #define BGPEN 0
  19. #define FGPEN 1
  20. #define LOPEN 2
  21. #define HIPEN 3
  22.  
  23. /* Event() return codes */
  24. #define DUNNO -1
  25. #define RESIZED 1
  26.  
  27. #define TRAIL (Trails.Flags&CHECKED)
  28. #define POLYS (ShoPoly.Flags&CHECKED)
  29.  
  30. /****************************************************************/
  31. /******* Built-Ins **********************************************/
  32. /****************************************************************/
  33.  
  34. extern LONG GfxBase;
  35. extern LONG IntuitionBase;
  36.  
  37. extern struct Window *OpenWindow();
  38. extern struct IntuiMessage *GetMsg();
  39.  
  40. /****************************************************************/
  41. /******* Local IntuiJunk ****************************************/
  42. /****************************************************************/
  43.  
  44. struct Window *w;
  45. struct RastPort *rp;
  46. struct IntuiMessage *message;
  47. USHORT class;
  48.  
  49. struct TextAttr ROMFont8 = {
  50.     "Topaz80",8,0,0        /* Define text font for our screen */
  51. };
  52.  
  53. struct IntuiText SText[2] = {
  54.     {LOPEN,BGPEN,JAM1,CHECKWIDTH,0,&ROMFont8,"Trails",NULL},
  55.     {LOPEN,BGPEN,JAM1,CHECKWIDTH,0,&ROMFont8,"Poly",  NULL}
  56. };
  57.  
  58. struct MenuItem ShoPoly = {
  59.     NULL,            /* NextItem */
  60.     0,9,(CHECKWIDTH+50), 9,    /* Corner, Size */
  61.     ITEMTEXT|HIGHCOMP|ISDRAWN|ITEMENABLED|CHECKIT|MENUTOGGLE, /* Flags */
  62.     0L,            /* MutualExclude */
  63.     (APTR)&SText[1], NULL,    /* ItemFill, SelectFill */
  64.     '\0',            /* Command */
  65.     NULL, NULL        /* SubItem, NextSelect */
  66. };
  67.  
  68. struct MenuItem Trails = {
  69.     &ShoPoly,        /* NextItem */
  70.     0,0,(CHECKWIDTH+50), 9,    /* Corner, Size */
  71.     ITEMTEXT|HIGHCOMP|ISDRAWN|ITEMENABLED|CHECKIT|MENUTOGGLE, /* Flags */
  72.     0L,            /* MutualExclude */
  73.     (APTR)&SText[0], NULL,    /* ItemFill, SelectFill */
  74.     '\0',            /* Command */
  75.     NULL, NULL        /* SubItem, NextSelect */
  76. };
  77.  
  78. struct Menu Options = {
  79.     NULL,            /* NextMenu */
  80.     0,0,(CHECKWIDTH+54),9,    /* Corner, Size */
  81.     MIDRAWN|MENUENABLED,    /* Flags */
  82.     "Snake",        /* MenuName */
  83.     &Trails            /* FirstItem */
  84. };
  85.  
  86. /****************************************************************/
  87. /******* Window *************************************************/
  88. /****************************************************************/
  89.  
  90. struct NewWindow nw = {
  91.     100,50,            /* Starting corner */
  92.     300,100,        /* Width, Height */
  93.     LOPEN,HIPEN,        /* DetailPen, BlockPen */
  94.     CLOSEWINDOW|NEWSIZE,    /* IDCMPFlags (Don't need MENUPICK!) */
  95.     WINDOWDEPTH|ACTIVATE|WINDOWDRAG|WINDOWCLOSE|
  96.         SMART_REFRESH|WINDOWSIZING,    /* Flags */
  97.     NULL,            /* FirstGadget */
  98.     NULL,            /* Pointer to checkmark */
  99.     "Snake",        /* title */
  100.     NULL,            /* Screen */
  101.     NULL,            /* Bitmap */
  102.     50,50,640,400,        /* Size limits */
  103.     WBENCHSCREEN        /* Type */
  104. };
  105.  
  106. /****************************************************************/
  107. /******* Spline Vars ********************************************/
  108. /****************************************************************/
  109.  
  110. float coeffs[4][MAXVERT];
  111. float P[2][4], Pv[2][4], xlf, ylf;
  112. SHORT xlim, ylim;
  113. SHORT DispVerts[(2*MAXVERT)];
  114. SHORT OldVerts[16][(2*MAXVERT)];
  115. SHORT control[8], oldcont[16][8];
  116.  
  117. /****************************************************************/
  118. /****** Function Typing *****************************************/
  119. /****************************************************************/
  120.  
  121. extern VOID AmiSetup();
  122. extern VOID SplineSetup();
  123. extern VOID CalcSnake();
  124. extern SHORT Event();
  125.  
  126. /****************************************************************/
  127. /******* Execution Begins Here **********************************/
  128. /****************************************************************/
  129.  
  130. VOID _main()
  131. {
  132.     register UWORD i;
  133.     register BOOL  k;
  134.     UWORD onward = 0;
  135.     UWORD SnakeColr = FGPEN;
  136.     UWORD PolyColr = HIPEN;
  137.     LONG Iterate = 0L;
  138.  
  139.     AmiSetup();
  140.     SplineSetup();
  141.  
  142.     xlim = w->Width - 3;
  143.     ylim = w->Height - 2;
  144.     xlf = (float)xlim;
  145.     ylf = (float)ylim;
  146.     for(i=0;i<4;++i) {
  147.        P[0][i]  = (float)(rand() % (xlim-2)  + 1);    /* random start */
  148.        P[1][i]  = (float)(rand() % (ylim-14) + 13);
  149.        Pv[0][i] = (float)(rand() % 10 + 1);        /* and vector */
  150.        Pv[1][i] = (float)(rand() % 10 + 1);
  151.     }
  152.  
  153.     class = NULL;
  154.     do {
  155.        CalcSnake();
  156.        if ((!TRAIL) && (onward)) {
  157.           SetAPen(rp,BGPEN);            /* erase old */
  158.           onward = Iterate & 15;    
  159.           Move(rp,OldVerts[onward][0],OldVerts[onward][1]);
  160.           PolyDraw(rp,MAXVERT,&OldVerts[onward][0]);
  161.           if (POLYS) {
  162.              Move(rp,oldcont[onward][0],oldcont[onward][1]);
  163.              PolyDraw(rp,4,&oldcont[onward][0]);
  164.           }
  165.        }
  166.  
  167.        SetAPen(rp,SnakeColr);                /* Draw new Curve */
  168.        Move(rp,DispVerts[0],DispVerts[1]);
  169.        PolyDraw(rp,MAXVERT,&DispVerts[0]);
  170.  
  171.        if (POLYS) {
  172.           SetAPen(rp,PolyColr);
  173.           Move(rp,control[0],control[1]);
  174.           PolyDraw(rp,4,&control[0]);
  175.        }
  176.        if((rand() & 127) < 2) {            /* new color */
  177.           PolyColr = SnakeColr;
  178.           if (++SnakeColr > 3) SnakeColr = 1;
  179.        }
  180.  
  181.        onward = (10 + Iterate++) & 15;
  182.        for (i=0; i<(2*MAXVERT); ++i)        /* old curve */
  183.           OldVerts[onward][i] = DispVerts[i];
  184.        for (i=0; i<8; ++i)                /* old control points */
  185.           oldcont[onward][i] = control[i];
  186.  
  187.        for(i=0;i<4;++i) {            /* update control points */
  188.           P[0][i] += Pv[0][i];        /* new control points */
  189.           P[1][i] += Pv[1][i];
  190.           if(P[0][i] < 2.0)    {        /* clipping */
  191.          P[0][i] = 2.0;    Pv[0][i] = -Pv[0][i];
  192.           } else if(P[0][i] > xlf) {
  193.          P[0][i] = xlf;    Pv[0][i] = -Pv[0][i];
  194.           }
  195.           if(P[1][i] < 10.0)    {
  196.          P[1][i] = 10.0; Pv[1][i] = -Pv[1][i];
  197.           } else if(P[1][i] > ylf) {
  198.          P[1][i] = ylf;     Pv[1][i] = -Pv[1][i];
  199.           }
  200.           if(((rand() >> 5) & 127) < 2) {    /* change x speed */
  201.          k = (Pv[0][i] < 0.0);
  202.          Pv[0][i] = (rand() >> 5) & 7;
  203.          if (k) Pv[0][i] = -Pv[0][i];
  204.           }
  205.           if(((rand() >> 5) & 255) < 50) {    /* change y speed */
  206.          k = (Pv[1][i] < 0.0);
  207.          Pv[1][i] = (rand() >> 5) & 7;
  208.          if (k) Pv[1][i] = -Pv[1][i];
  209.           }
  210.        }
  211.        onward = 1;
  212.        if(w->UserPort->mp_SigBit) {
  213.           message = GetMsg(w->UserPort);
  214.           if(message != NULL) {
  215.              class = message->Class;
  216.              ReplyMsg(message);
  217.           }
  218.        }
  219.     } while(Event());
  220.  
  221.     ClearMenuStrip(w);
  222.     CloseWindow(w);
  223.     CloseLibrary(IntuitionBase);
  224.     CloseLibrary(GfxBase);
  225. }
  226.  
  227. /****************************************************************/
  228. /****** Analyse IDCMP events ************************************/
  229. /****************************************************************/
  230.  
  231. SHORT Event()
  232. {
  233.     switch(class) {
  234.        case CLOSEWINDOW:
  235.           return(NULL);
  236.           break;
  237.        case NEWSIZE:
  238.           class = NULL;
  239.           xlim = w->Width - 3;
  240.           ylim = w->Height -2;
  241.           xlf = (float)xlim;
  242.           ylf = (float)ylim;
  243.           return(RESIZED);
  244.           break;
  245.     }
  246.     return(DUNNO);
  247. }
  248.  
  249. /****************************************************************/
  250. /****** Set up display & libraries ******************************/
  251. /****************************************************************/
  252.  
  253. VOID AmiSetup()
  254. {
  255.     if ((GfxBase = OpenLibrary("graphics.library",LIBRARY_VERSION))
  256.         == NULL) {
  257.        Exit(20);
  258.     }
  259.     if ((IntuitionBase = OpenLibrary("intuition.library",LIBRARY_VERSION))
  260.         == NULL) {
  261.        CloseLibrary(GfxBase);
  262.        Exit(20);
  263.     }
  264.     if ((w = OpenWindow(&nw)) == NULL) {
  265.        CloseLibrary(IntuitionBase);
  266.        CloseLibrary(GfxBase);
  267.        Exit(20);
  268.     }
  269.     rp = w->RPort;
  270.     SetAPen(rp,HIPEN);
  271.     SetDrMd(rp,JAM1);
  272.     SetMenuStrip(w,&Options);
  273. }
  274.  
  275. /****************************************************************/
  276. /******* Precalculate Spline Coefficients ***********************/
  277. /****************************************************************/
  278.  
  279. VOID SplineSetup()
  280. {
  281.     float t;
  282.     UWORD i;
  283.     for (i=0; i<MAXVERT; ++i) {
  284.       t = (float)i / (float)(MAXVERT-1);
  285.       coeffs[3][i]  = 1.0 - t;
  286.       coeffs[2][i]  = coeffs[3][i] * coeffs[3][i];
  287.       coeffs[0][i]  = t * (coeffs[1][i] = t*t);
  288.       coeffs[1][i] *= (3.0 * coeffs[3][i]);
  289.       coeffs[3][i] *= coeffs[2][i];
  290.       coeffs[2][i] *= (3.0 * t);
  291.     }
  292. }
  293.  
  294.  
  295. /****************************************************************/
  296. /****** Recalculate snake vertices ******************************/
  297. /****************************************************************/
  298.  
  299. VOID CalcSnake()
  300. {
  301.     register i, j;
  302.     float xt, yt;
  303.     short ndx;
  304.     ndx = 0;
  305.     for (i=0; i<MAXVERT; ++i) {
  306.       xt = yt = 0.0;
  307.       for (j=0; j<4; ++j) {
  308.         xt += P[0][j] * coeffs[j][i];
  309.         yt += P[1][j] * coeffs[j][i];
  310.       }
  311. #ifdef DEBUG
  312.       /* clip is unnessesary because of bounding-poly adherence */
  313.       if (xt<2.0)    xt = 2.0;
  314.       if (xt>xlim)    xt = xlim;
  315.       if (yt<12.0)    yt = 12.0;
  316.       if (yt>ylim)    yt = ylim;
  317. #endif DEBUG
  318.       DispVerts[ndx++] = (SHORT)xt;
  319.       DispVerts[ndx++] = (SHORT)yt;
  320.     }
  321.     ndx = 0;
  322.     for (i=0; i<4; ++i) {
  323.       control[ndx++] = (SHORT)P[0][i];
  324.       control[ndx++] = (SHORT)P[1][i];
  325.     }
  326. }
  327.  
  328. /****************************************************************/
  329. /******************************************************** eof ***/
  330. /****************************************************************/
  331.